package com.jintian.smart.kernel.flowable.component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.StringTemplateResourceLoader;
import org.beetl.ext.spring6.BeetlGroupUtilConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public abstract class BeetlStringRender implements ApplicationContextAware {
    @Autowired
    private BeetlGroupUtilConfiguration beetlGroupUtilConfiguration;

    private GroupTemplate groupTemplate;

    protected ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    @SuppressWarnings({"rawtypes", "unchecked"})
    private void init() {

        GroupTemplate source = this.beetlGroupUtilConfiguration.getGroupTemplate();
        StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();
        GroupTemplate target = new GroupTemplate(resourceLoader,
                beetlGroupUtilConfiguration.getGroupTemplate().getConf());
        try {
            {
                Field filed = GroupTemplate.class.getDeclaredField("fnMap");
                filed.setAccessible(true);

                Map targetFnMap = (Map) filed.get(target);
                Map backup = new HashMap<>();
                backup.putAll(targetFnMap);

                Map sourceFnMap = (Map) filed.get(source);
                targetFnMap.putAll(sourceFnMap);
                targetFnMap.putAll(backup);
            }

            {
                Field filed = GroupTemplate.class.getDeclaredField("formatMap");
                filed.setAccessible(true);

                Map targetFormatMap = (Map) filed.get(target);
                Map backup = new HashMap<>();
                backup.putAll(targetFormatMap);

                Map sourceFormatMap = (Map) filed.get(source);
                targetFormatMap.putAll(sourceFormatMap);
                targetFormatMap.putAll(backup);
            }
            this.groupTemplate = target;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    protected String beetlRender(String template, Map<String, Object> variants) {
        Template t = this.groupTemplate.getTemplate(template);
        t.binding(variants);
        return t.render();
    }
}
